<?php
/**
 * PhpStorm
 * User: zucheng
 * Date: 2019/3/23
 */

namespace App\Http\Controllers\Api\V1;

use App\Library\Common;
use App\Messages\ShippingStatus25Driver;
use App\Messages\ShippingStatus25Order;
use App\Messages\ShippingStatus42Driver;
use App\Messages\ShippingStatus42Order;
use App\Messages\ShippingStatus50Driver;
use App\Mail\OrderShipped;
use App\Models\Card;
use App\Models\Member;
use App\Models\MemberAudit;
use App\Models\MemberRelation;
use App\Models\Owner;
use App\Models\Allowance;
use App\Models\Loss;
use App\Models\Order;
use App\Models\OwnerRoutes;
use App\Models\PayExport;
use App\Models\Shipping;
use App\Models\ShippingPay;
use App\Services\NotificationService;
use App\Services\RouteService;
use App\Services\ShippingService;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Validator;
use App\Http\Controllers\Api\ApiController;
use Illuminate\Http\Request;
use DB;
use Mail;

class OwnerController extends ApiController
{
    /**
     * 获取货主基本信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getInfo(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $user = Member::query()
                ->with(['owner', 'audit'])
                ->where('v_members.uuid', $request->get('user_uuid'))
                ->firstOrFail();
            $data = [
                'uuid' => $user->uuid,
                'name' => $user->name,
                'phone' => $user->phone,
                'status' => $user->owner->status ?? 0,
                'audit_status' => $user->audit->audit_status ?? 0,
                'audit_des' => $user->audit->audit_des ?? '',
            ];

            return $this->success('success', $data);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 身份认证
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function identityVerify(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
                'name' => 'required',
                'card_no' => 'required|min:16|max:18',
                'pic_card_front' => 'required',
                'pic_card_back' => 'required',
                'pic_card_face' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $user = Member::with('owner')
                ->where('uuid', $request->get('user_uuid'))
                ->firstOrFail();
            if (!$user->owner) {
                throw new \Exception("非货主不能验证.");
            }

            $user->name = $request->get('name');

            // 更新货主信息
            $status = $user->owner->status;
            if ($user->owner->status == Owner::STATUS_DEFAULT) {
                $status = Owner::STATUS_IDENTITY;
            } elseif ($user->owner->status == Owner::STATUS_COMPANY) {
                $status = Owner::STATUS_END;
            }
            $user->owner->card_no = $request->get('card_no');
            $user->owner->pic_card_front = $request->get('pic_card_front');
            $user->owner->pic_card_back = $request->get('pic_card_back');
            $user->owner->pic_card_face = $request->get('pic_card_face');
            $user->owner->status = $status;
            $user->owner->save();

            $user->save();

            // 更新审核状态
            $this->upAuditStatus($request->get('user_uuid'));

            return $this->success('身份认证成功', ['user_uuid' => $user->uuid]);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 企业认证
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function companyVerify(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
                'company_name' => 'required',
                'pic_company_certificate' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $user = Owner::where('uuid', $request->get('user_uuid'))->firstOrFail();

            // 更新货主信息
            $status = $user->status;
            if ($user->status == Owner::STATUS_DEFAULT) {
                $status = Owner::STATUS_COMPANY;
            } elseif ($user->status == Owner::STATUS_IDENTITY) {
                $status = Owner::STATUS_END;
            }
            $user->company_name = $request->get('company_name');
            $user->pic_company_certificate = $request->get('pic_company_certificate');
            $user->status = $status;
            $user->save();

            // 更新审核状态
            $this->upAuditStatus($request->get('user_uuid'));

            return $this->success('企业认证成功', ['user_uuid' => $user->uuid]);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 新增或者更新货主认证 审核信息
     * @param $uuid 用户唯一标识
     * @return bool
     */
    protected function upAuditStatus($uuid)
    {
        $owner = Owner::onWriteConnection()->where('uuid', $uuid)->first();
        if ($owner->status == Owner::STATUS_END) {
            $auditInfo = MemberAudit::onWriteConnection()->where('uuid', $uuid)->first();
            if (empty($auditInfo)) {
                // 新建审核记录
                MemberAudit::create([
                    'member_id' => $owner->member_id,
                    'uuid' => $uuid,
                    'audit_status' => MemberAudit::STATUS_WAIT,
                ]);
            } else if ($auditInfo->audit_status == MemberAudit::STATUS_NO_PASS) {
                // 更新审核状态
                $auditInfo->audit_status = MemberAudit::STATUS_WAIT;
                $auditInfo->save();
            }
        }

        return true;
    }

    /**
     * 获取货主认证信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getVerifyInfo(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'owner_uuid' => 'required|size:36',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $user = Member::query()
                ->with(['owner', 'audit'])
                ->where('v_members.uuid', $request->get('owner_uuid'))
                ->firstOrFail();
            $data = [
                'uuid' => $user->uuid,
                'name' => $user->name ?? '',
                'phone' => $user->phone ?? '',
                'card_no' => $user->owner->card_no ?? '',
                'pic_card_front' => $user->owner->pic_card_front ?? '',
                'pic_card_back' => $user->owner->pic_card_back ?? '',
                'pic_card_face' => $user->owner->pic_card_face ?? '',
                'company_name' => $user->owner->company_name ?? '',
                'pic_company_certificate' => $user->owner->pic_company_certificate ?? '',
                'status' => $user->owner->status ?? 0,
                'audit_status' => $user->audit->audit_status ?? 0,
                'audit_des' => $user->audit->audit_des ?? '',
            ];

            return $this->success('success', $data);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 装货确认
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function confirmLoad(Request $request)
    {
        DB::beginTransaction();
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
//                'shipment_remark' => 'required',
//                'card_number'     => 'numeric',
//                'allowance_fee'   => 'integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $shipping = Shipping::where('shipping_no', $request->get('shipping_no'))->firstOrFail();
            if ($shipping->global_status != Shipping::GLOBAL_DRIVER_LOADED) {
                throw new \Exception('司机还未完成装货磅单上传');
            }

            // 更新货运表
            $shipping->global_status = Shipping::GLOBAL_SENDER_LOAD_CONFIRM;
            if (!empty($request->get('shipment_remark', ''))) {
                $shipping->shipment_remark = $request->get('shipment_remark');
            }
            if (!empty($request->get('load_num', ''))) {
                $shipping->load_num = $request->get('load_num');
            }
            $shipping->save();

            // 油卡相关
            if (!empty($request->get('card_number', '')) && !empty($request->get('allowance_fee', 0))) {
                $card = Card::where('card_number', $request->get('card_number'))->first();
                if (empty($card)) {
                    throw new \Exception('找不到加油卡信息');
                }

                // 记录补贴信息
                Allowance::create([
                    'shipping_id' => $shipping->id,
                    'card_number' => $request->get('card_number'),
                    'allowance_fee' => $request->get('allowance_fee'),
                    'status' => Allowance::STATUS_USEING,
                ]);

                // 更新油卡状态 使用中
                Card::where('card_number', $request->get('card_number'))
                    ->update([
                        'card_status' => Card::CARD_STATUS_DISABLED,
                        'allowance_total_fee' => $card->allowance_total_fee + $request->get('allowance_fee')
                    ]);
            }

            DB::commit();


            //++++++@start - 发货人确认装货，发送通知给司机和发单人 - 运单状态为25
            // @step1 发送通知给司机
            $msgContent = sprintf('运单号为%s的发货榜单已确认', $request->get('shipping_no'));
            $params = [];
            $oDriver = Member::query()->where('uuid', $shipping->driver_uuid)->firstOrFail();
            if ($oDriver->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type' => 'user_alias',
                    'alias' => $shipping->driver_uuid,
                    "ticker" => "发货人确认装货",
                    "title" => "发货人确认装货",
                    "text" => $msgContent,
                    "after_open" => "go_app",
                    "description" => "发货人确认装货",
                ];
                $params['payload']['extra']['cust_type'] = 1; // type：1 跳转运单页 附参数shippingId
                $params['payload']['extra']['cust_shippingid'] = $request->get('shipping_no');
            }
            if ($oDriver->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert' => [
                        'title' => '发货人确认装货',
                        'body' => $msgContent,
                    ],
                    'alias_type' => 'user_alias',
                    'alias' => $shipping->driver_uuid,
                    "description" => '发货人确认装货',
                ];
                $params['payload']['cust_type'] = 1; // type：1 跳转运单页 附参数shippingId
                $params['payload']['cust_shippingid'] = $request->get('shipping_no');
            }
            NotificationService::fire($request->get('user_uuid'), $params, new ShippingStatus25Driver($request->get('shipping_no')));

            // @step2 发送通知给发单人
            $oOrder = Order::query()->where('id', $shipping->order_id)->firstOrFail();
            $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($oOrder->route_id, new OwnerRoutes(), [1, 2, 3, 4], [1, 2, 3, 4]);
            $msgContent = sprintf('送往%s的任务，运单号为%s的司机%s，已经完成装货，手机号为%s',
                $routeInfo['dstDetail'],
                $request->get('shipping_no'),
                $oDriver->name,
                $oDriver->phone
            );

            $oCreator = Member::query()->where('uuid', $oOrder->create_uuid)->firstOrFail();
            if ($oCreator->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type' => 'user_alias',
                    'alias' => $oOrder->create_uuid,
                    "ticker" => "发货人确认装货",
                    "title" => "发货人确认装货",
                    "text" => $msgContent,
                    "after_open" => "go_app",
                    "description" => "发货人确认装货",
                ];
            }
            if ($oCreator->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert' => [
                        'title' => '发货人确认装货',
                        'body' => $msgContent,
                    ],
                    'alias_type' => 'user_alias',
                    'alias' => $oOrder->create_uuid,
                    "description" => '发货人确认装货',
                ];
            }
            NotificationService::fire($oOrder->create_uuid, $params, new ShippingStatus25Order(
                $routeInfo['dstDetail'],
                $request->get('shipping_no'),
                $oDriver->name,
                $oDriver->phone
            ));
            //++++++@end - 发货人确认装货，发送通知给司机和发单人


            return $this->success('success');
        } catch (ModelNotFoundException $e) {
            DB::rollback();

            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            DB::rollback();

            return $this->error($e->getMessage());
        }
    }

    /**
     * 卸货确认 废弃
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function confirmUnload(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
                'deliver_remark' => 'required',
                'loss_total_num' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $shipping = Shipping::where('shipping_no', $request->get('shipping_no'))->firstOrFail();
            if ($shipping->global_status != Shipping::GLOBAL_DRIVER_UNLOADED) {
                throw new \Exception('司机还未完成卸货磅单上传');
            }

            // 更新货运表
            $shipping->global_status = Shipping::GLOBAL_RECEIVER_UNLOAD_CONFIRM;
            $shipping->deliver_remark = $request->get('deliver_remark');
            $shipping->status = Shipping::$statusUnLoadComplete;
            $shipping->save();

            // 记录扣损信息
            $order = Order::findOrFail($shipping->order_id);
            $lossTotalNum = $request->get('loss_total_num');
            $lossNum = $lossTotalNum - $order->loss_limit;
            $data = [
                'shipping_id' => $shipping->id,
                'loss_total_num' => $lossTotalNum,
            ];
            if ($lossNum > 0 && $order->loss_deduct == Order::LOSS_DEDUCT_Y) {
                $data['loss_num'] = $lossNum;
                $data['loss_amount'] = $lossNum * $order->loss_price;
            }
            Loss::create($data);

            return $this->success('success');
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 扣损费用计算
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function lossCalculate(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            if ($request->has('loss_total_num')) {
                $data = ShippingService::getInstance()->calculateShippingLossFee($request->get('shipping_no'), $request->get('loss_total_num'));
            } else {
                $data = ShippingService::getInstance()->calculateShippingLossFee($request->get('shipping_no'));
            }

            return $this->success('success', $data);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 扣损费用确定
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function confirmLossFee(Request $request)
    {
        DB::beginTransaction();
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
                //'deliver_remark' => 'required',
                'loss_total_num' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            ShippingService::getInstance()->saveShippingLossFee($request->get('shipping_no'), $request->get('loss_total_num'), $request->get('deliver_remark', ''));

            DB::commit();

            return $this->success('success');
        } catch (ModelNotFoundException $e) {
            DB::rollback();
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            DB::rollback();
            return $this->error($e->getMessage());
        }
    }

    /**
     * 货运费用计算
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function amountCalculate(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $data = ShippingService::getInstance()->calculateShippingAmount($request->get('shipping_no'));

            return $this->success('success', $data);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 货运费用确定
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function confirmShippingAmount(Request $request)
    {
        DB::beginTransaction();
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            ShippingService::getInstance()->saveShippingAmount($request->get('shipping_no'));

            DB::commit();

            //++++++@start - 发送通知给司机和发单人 - 运单状态为42
            // @step1 发送通知给司机
            $oShipping = Shipping::query()->where('shipping_no', $request->get('shipping_no'))->firstOrFail();
            $oOrder = Order::query()->where('id', $oShipping->order_id)->firstOrFail();
            $oDriver = Member::query()->where('uuid', $oShipping->driver_uuid)->firstOrFail();
            $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($oOrder->route_id, new OwnerRoutes(), [1, 2, 3, 4], [1, 2, 3, 4]);

            $msgContent = sprintf('运单号为%s的收货榜单已确认。', $request->get('shipping_no'));
            $params = [];
            if ($oDriver->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type' => 'user_alias',
                    'alias' => $oShipping->driver_uuid,
                    "ticker" => "收货榜单已确认",
                    "title" => "收货榜单已确认",
                    "text" => $msgContent,
                    "after_open" => "go_app",
                    "description" => "收货榜单已确认",
                ];
                $params['payload']['extra']['cust_type'] = 1;
                $params['payload']['extra']['cust_shippingid'] = $oShipping->shipping_no;
            }
            if ($oDriver->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert' => [
                        'title' => '收货榜单已确认',
                        'body' => $msgContent,
                    ],
                    'alias_type' => 'user_alias',
                    'alias' => $oShipping->driver_uuid,
                    "description" => '收货榜单已确认',
                ];
                $params['payload']['cust_type'] = 1;
                $params['payload']['cust_shippingid'] = $oShipping->shipping_no;
            }
            NotificationService::fire($oShipping->driver_uuid, $params, new ShippingStatus42Driver($request->get('shipping_no')));

            // @step2 发送通知给发单人
            $msgContent = sprintf('送往%s的任务，运单号为%s的司机%s已经完成卸货 ，手机号为%s',
                $routeInfo['dstDetail'],
                $oShipping->shipping_no,
                $oDriver->name,
                $oDriver->phone
            );
            $params = [];
            $oCreator = Member::query()->where('uuid', $oOrder->create_uuid)->firstOrFail();
            if ($oDriver->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type' => 'user_alias',
                    'alias' => $oCreator->create_uuid,
                    "ticker" => "收货榜单已确认",
                    "title" => "收货榜单已确认",
                    "text" => $msgContent,
                    "after_open" => "go_app",
                    "description" => "收货榜单已确认",
                ];
            }
            if ($oDriver->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert' => [
                        'title' => '收货榜单已确认',
                        'body' => $msgContent,
                    ],
                    'alias_type' => 'user_alias',
                    'alias' => $oCreator->create_uuid,
                    "description" => '收货榜单已确认',
                ];
            }
            NotificationService::fire($oCreator->create_uuid, $params, new ShippingStatus42Order(
                $routeInfo['dstDetail'],
                $oShipping->shipping_no,
                $oDriver->name,
                $oDriver->phone
            ));
            //++++++@end - 发送通知给司机和发单人 - 运单状态为42


            return $this->success('success');
        } catch (ModelNotFoundException $e) {
            DB::rollback();
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            DB::rollback();
            return $this->error($e->getMessage());
        }
    }

    /**
     * 货主确认运单费用后的数据展示
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function afterConfirmShippingAmount(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $shippingNo = $request->get('shipping_no');

            $fields = [
                'v_shipping_pay.load_num',
                'v_shipping_pay.load_amount',
                'v_shipping_pay.loss_amount',
                'v_shipping_pay.actual_amount',
                'v_shipping_pay.status',
                'v_shipping_pay.created_at',
                'v_shipping_pay.updated_at',
            ];
            $oShippingPay = ShippingPay::select($fields)
                ->leftJoin('v_shipping', 'v_shipping.id', '=', 'v_shipping_pay.shipping_id')
                ->where('v_shipping.shipping_no', $shippingNo)
                ->first();
            if (is_null($oShippingPay)) {
                return $this->success('没有获取到数据');
            }

            return $this->success('success', $oShippingPay->toArray());
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 财务列表
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function payList(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
//                'pay_status' => 'required',
                'page' => 'required|integer',
                'limit' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            // 用户权限判断 只有财务和货主能操作
            $ownerUuid = '';
            $user = Member::where('uuid', $request->get('user_uuid'))->firstOrFail();
            if ($user->role_id == Member::ROLE_OWNER) {
                $ownerUuid = $user->uuid;
            } else if ($user->role_id == 0) {
                $userRelation = MemberRelation::where('member_id', $user->id)->get()->toArray();
                if (count($userRelation) > 1) {
                    throw new \Exception('用户有误，财务不能属于多个货主');
                }
                $roles = explode(',', $userRelation[0]['role_id']);
                if (!in_array(Member::ROLE_FINANCE, $roles)) {
                    throw new \Exception('非财务用户，不能操作此页面');
                }
                $owner = Member::where('id', $userRelation[0]['parent_id'])->where('role_id', Member::ROLE_OWNER)->first();
                if (empty($owner)) {
                    throw new \Exception('找不到对应的货主信息');
                }
                $ownerUuid = $owner->uuid;
            }
            if (empty($ownerUuid)) {
                throw new \Exception('用户权限不允许');
            }

            // 查询数据
            $fields = [
                'v_shipping.shipping_no',
                'v_shipping.deliver_end_time as unload_time',
                'o.order_no',
                'mem.name as driver_name',
                'mem.phone as driver_phone',
                'bank.bank_card_no',
                'pay.actual_amount',
                'pay.status as pay_status',
            ];
            $query = Shipping::leftJoin('v_orders as o', 'o.id', '=', 'v_shipping.order_id')
                ->leftJoin('v_shipping_pay as pay', 'pay.shipping_id', '=', 'v_shipping.id')
                ->leftJoin('v_driver_bank as bank', 'bank.id', '=', 'pay.bank_id')
                ->leftJoin('v_members as mem', 'mem.uuid', '=', 'v_shipping.driver_uuid')
                ->select($fields)
                ->where('o.owner_uuid', $ownerUuid)
                ->where('pay.status', $request->get('pay_status'));

            if ($request->has('order_no')) {
                $query->where('o.order_no', $request->get('order_no'));
            }
            if ($request->has('shipping_no')) {
                $shippingNO = explode(',', $request->get('shipping_no'));
                $query->whereIn('v_shipping.shipping_no', $shippingNO);
            }
            if ($request->has('driver_name')) {
                $query->where('mem.name', $request->get('driver_name'));
            }

            $res = $query->paginate($request->get('limit', self::DEFAULT_PAGE_LIMIT))
                ->toArray();

            return $this->table($res['data'], $res['total']);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 财务支付完成旧版
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function payDoneOld(Request $request)
    {
        DB::beginTransaction();
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $shipping = Shipping::where('shipping_no', $request->get('shipping_no'))->firstOrFail();
            $shippingPay = ShippingPay::where('shipping_id', $shipping->id)->firstOrFail();

            $shippingPay->status = ShippingPay::STATUS_PAYED;
            if (!empty($request->get('remark', ''))) {
                $shippingPay->remark = $request->get('remark');
            }
            if (!empty($request->get('result_pic', ''))) {
                $shippingPay->pic = $request->get('result_pic');
            }
            $shippingPay->save();

            $shipping->pay_status = Shipping::PAY_DONE;
            $shipping->global_status = Shipping::GLOBAL_OWNER_PAY;
            $shipping->save();

            DB::commit();

            //++++++@start - 发送通知给司机 - 运单状态为50
            $oOrder = Order::query()->where('id', $shipping->order_id)->firstOrFail();
            $oShippingPay = ShippingPay::query()->where('shipping_id', $shipping->id)->firstOrFail();
            $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($oOrder->route_id, new OwnerRoutes(), [1, 2, 3, 4], [1, 2, 3, 4]);

            $msgContent = sprintf('有运费已经到账，请查收。目的地为%s，运单号为%s，实付金额为%s元。',
                $routeInfo['dstDetail'],
                $request->get('shipping_no'),
                $oShippingPay->actual_amount
            );

            $params = [];
            $oDriver = Member::query()->where('uuid', $shipping->driver_uuid)->firstOrFail(); // 发货人信息
            if ($oDriver->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type' => 'user_alias',
                    'alias' => $shipping->driver_uuid,
                    "ticker" => "有运费已经到账，请查收",
                    "title" => "有运费已经到账，请查收",
                    "text" => $msgContent,
                    "after_open" => "go_app",
                    "description" => "有运费已经到账，请查收",
                ];
                $params['payload']['extra']['cust_type'] = 1;
                $params['payload']['extra']['cust_shippingid'] = $request->get('shipping_no');
            }
            if ($oDriver->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert' => [
                        'title' => '有运费已经到账，请查收',
                        'body' => $msgContent,
                    ],
                    'alias_type' => 'user_alias',
                    'alias' => $shipping->driver_uuid,
                    "description" => '有运费已经到账，请查收',
                ];
                $params['payload']['cust_type'] = 1;
                $params['payload']['cust_shippingid'] = $request->get('shipping_no');
            }
            NotificationService::fire($shipping->driver_uuid, $params, new ShippingStatus50Driver(
                $routeInfo['dstDetail'],
                $request->get('shipping_no')
            ));
            //++++++@end - 发送通知给财务 - 运单状态为50


            return $this->success('success');
        } catch (ModelNotFoundException $e) {
            DB::rollback();

            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            DB::rollback();

            return $this->error($e->getMessage());
        }
    }


    /**
     * 财务支付完成
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function payDone(Request $request)
    {
        $pay_type = $request->get('pay_type', 0);
        $pay_type_text = $request->get('pay_type_text', '');
        $carrier_platform = $request->get('carrier_platform', 0);

        DB::beginTransaction();
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
                //'pay_type_text' => 'required',
                'pay_type' => 'number|size:2',
                'carrier_platform' => 'number|size:2',

            ], ['required' => ':attribute参数必须传输'], ['shipping_no' => '运单', 'pay_type_text' => '支付方式', 'carrier_platform' => '承运人平台']);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            try {
                $shipping = Shipping::where('shipping_no', $request->get('shipping_no'))->firstOrFail();
            } catch (\Exception $exception) {
                throw new \Exception('发货单不存在');
            }
            try {
                $shippingPay = ShippingPay::where('shipping_id', $shipping->id)->firstOrFail();
            } catch (\Exception $exception) {
                throw new \Exception('运单不存在');
            }


            $shippingPay->status = ShippingPay::STATUS_PAYED;
            if (!empty($request->get('remark', ''))) {
                $shippingPay->remark = $request->get('remark');
            }
            if (!empty($request->get('result_pic', ''))) {
                $shippingPay->pic = $request->get('result_pic');
            }

            $shippingPay->pay_type = $pay_type;
            $shippingPay->pay_type_text = $pay_type_text;
            $shippingPay->carrier_platform = $carrier_platform;
            $shippingPay->pay_time = date('Y-m-d H:i:s', time());
            $shippingPay->save();

            $shipping->pay_status = Shipping::PAY_DONE;
            $shipping->global_status = Shipping::GLOBAL_OWNER_PAY;
            $shipping->pay_type = $pay_type;
            $shipping->pay_type_text = $pay_type_text;
            $shipping->carrier_platform = $carrier_platform;
            $shipping->pay_time = date('Y-m-d H:i:s', time());
            //==sql 新增支付方式  支付平台  begin
            $shipping->save();

            DB::commit();

            //++++++@start - 发送通知给司机 - 运单状态为50
            $oOrder = Order::query()->where('id', $shipping->order_id)->firstOrFail();
            $oShippingPay = ShippingPay::query()->where('shipping_id', $shipping->id)->firstOrFail();
            $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($oOrder->route_id, new OwnerRoutes(), [1, 2, 3, 4], [1, 2, 3, 4]);

            $msgContent = sprintf('有运费已经到账，请查收。目的地为%s，运单号为%s，实付金额为%s元。',
                $routeInfo['dstDetail'],
                $request->get('shipping_no'),
                $oShippingPay->actual_amount
            );

            $params = [];
            $oDriver = Member::query()->where('uuid', $shipping->driver_uuid)->firstOrFail(); // 发货人信息
            if ($oDriver->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type' => 'user_alias',
                    'alias' => $shipping->driver_uuid,
                    "ticker" => "有运费已经到账，请查收",
                    "title" => "有运费已经到账，请查收",
                    "text" => $msgContent,
                    "after_open" => "go_app",
                    "description" => "有运费已经到账，请查收",
                ];
                $params['payload']['extra']['cust_type'] = 1;
                $params['payload']['extra']['cust_shippingid'] = $request->get('shipping_no');
            }
            if ($oDriver->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert' => [
                        'title' => '有运费已经到账，请查收',
                        'body' => $msgContent,
                    ],
                    'alias_type' => 'user_alias',
                    'alias' => $shipping->driver_uuid,
                    "description" => '有运费已经到账，请查收',
                ];
                $params['payload']['cust_type'] = 1;
                $params['payload']['cust_shippingid'] = $request->get('shipping_no');
            }
            NotificationService::fire($shipping->driver_uuid, $params, new ShippingStatus50Driver(
                $routeInfo['dstDetail'],
                $request->get('shipping_no')
            ));
            //++++++@end - 发送通知给财务 - 运单状态为50


            return $this->success('success');
        } catch (ModelNotFoundException $e) {
            DB::rollback();

            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            DB::rollback();

            return $this->error($e->getMessage());
        }
    }

    /**
     * 导出支付信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function exportPayResult(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
                'shipping_nos' => 'required',
                'export_email' => 'required|email',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            if (empty($request->get('shipping_nos', ''))) {
                throw new \Exception("请选择需要导出的运单号");
            }

            // 申请记录
            $data = [
                'export_uuid' => $request->get('user_uuid'),
                'shipping_nos' => $request->get('shipping_nos'),
                'export_email' => $request->get('export_email'),
            ];
            PayExport::create($data);

            // 邮件发送 todo
            $shipping = Shipping::whereIn('shipping_no', explode(',', $data['shipping_nos']))->get();
            Mail::to($data['export_email'])->send(new OrderShipped($shipping));

            return $this->success('success');
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 导出记录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function exportList(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $res = PayExport::query()
                ->where('export_uuid', $request->get('user_uuid'))
                ->orderBy('id', 'desc')
                ->paginate($request->get('limit', self::DEFAULT_PAGE_LIMIT))
                ->toArray();
            if (empty($res['data'])) {
                return $this->table();
            }
            $data = [];
            foreach ($res['data'] as $datum) {
                $data[] = [
                    'id' => $datum['id'],
                    'shipping_nos' => $datum['shipping_nos'],
                    'export_email' => $datum['export_email'],
                    'export_date' => date('Y-m-d', strtotime($datum['created_at']))
                ];
            }

            return $this->table($data, $res['total']);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 运单完结确认
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function shippingEnd(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            // todo

            return $this->success('success');
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /***
     * @author sql
     * 货主审核司机违约运单
     *思路:
     *   1.根据运单号码shipping_no,cancel_status=0,status=-2,pay_status=-2 获取运单信息
     *   2.获取到的运单信息，判断是否是当前货主的，不是，不可以修改
     *   3.设置cancel_examine_text(货主审核意见),cancel_status(审核状态)
     */
    public function examineCancelStatus(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required',
                'cancel_status' => 'required|numeric|regex:/^[1-2]{1}$/',
                'cancel_examine_text' => 'required',
                'owner_uuid' => 'required',
            ], ['required' => ':attribute为必填项', 'numeric' => ':attribute必须是数字'], ['shipping_no' => '运单', 'cancel_status' => '是否同意违约', 'cancel_examine_text' => '审核备注', 'owner_uuid' => '当前货主唯一标识']);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $shipping_no = $request->post('shipping_no');
            $cancel_status = $request->post('cancel_status');
            $owner_uuid = $request->post('owner_uuid');
            $cancel_examine_text = $request->post('cancel_examine_text');
            //1.根据运单号码shipping_no,cancel_status=0,status=-2,pay_status=-2 获取运单信息
            try {
                $info = Shipping::where('shipping_no', $shipping_no)
                    ->where('cancel_status', 0)
                    ->where('status', Shipping::GLOBAL_CANCEL_APPLAY)
                    ->firstOrFail();
            } catch (\Exception $e) {
                throw new \Exception('运单不存在，或已经被审核过');
            }
            //2.获取到的运单信息，判断是否是当前货主的，不是，不可以修改

            try {
                $orderInfo = Order::
                where('id', $info->order_id)
                    ->firstOrFail();
            } catch (\Exception $e) {
                throw new \Exception('发货单不存在');
            }
            if ($orderInfo->owner_uuid != $owner_uuid) {
                throw new \Exception('您不是此运单的货主，不能审核');
            }
            $info->cancel_examine_text = $cancel_examine_text;
            $info->cancel_status = $cancel_status;
            $info->status = Shipping::GLOBAL_CANCEL_A_STATUS;
            $info->global_status = Shipping::GLOBAL_CANCEL_A_STATUS;
            $info->cancel_examine_time = date('Y-m-d H:i:s', time());
            if ($info->save()) {
                return $this->success('审核成功');
            }
            throw new \Exception('审核失败');


        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

}